package com.cg.asm.license.generate;

import com.cg.asm.license.holder.LicenseManagerHolder;
import de.schlichtherle.license.*;

import javax.security.auth.x500.X500Principal;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.prefs.Preferences;

public class LicenseMake {
    // 证书名与证书所在路径
    private String licName;
    // 证书的发布日期
    private String issued;
    // 证书有效期范围的起始日期
    private String notBefore;
    // 证书有效期范围的结束日期
    private String notAfter;
    private String consumerType;
    private int consumerAmount;
    private String info;
    // 私钥的别名
    private String priAlias;
    // 该密码生成密钥对的密码
    private String privateKeyPwd;
    // 使用keytool生成密钥对时设置的密钥库的访问密码
    private String keyStorePwd;
    // 项目唯一识别码
    private String subject;
    // 秘钥库地址, 相对路径
    private String priPath;

    // 授权可安装系统的服务器IPv4地址
    private String serverIp4Address;
    // 授权可安装系统的服务器Mac地址
    private String serverMacAddress;

    // 数据秘钥
    private String dataKey;
    // 数据秘钥的密码
    private String dataKeyPwd;

    // 运行环境
    private String env;

    /**
     * X500Principal是一个证书文件的固有格式
     */
    private final static X500Principal DEFAULTHOLDERANDISSUER =
            new X500Principal("CN=wq,OU=iss,O=iss,L=bj,ST=bj,C=china");

    public LicenseMake(String confPath){
        initParam(confPath);
    }
    /**
     * 读取属性文件
     */
    public void initParam(String confPath){
        Properties prop = new Properties();
        InputStream in = this.getClass().getClassLoader().getResourceAsStream(confPath);
        try {
            prop.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        priAlias = prop.getProperty("private.key.alias");
        privateKeyPwd = prop.getProperty("private.key.pwd");
        keyStorePwd = prop.getProperty("key.store.pwd");
        subject = prop.getProperty("subject");
        priPath = prop.getProperty("priPath");
        licName = prop.getProperty("licName");

        // license content
        issued = prop.getProperty("issuedTime");
        notBefore = prop.getProperty("notBefore");
        notAfter = prop.getProperty("notAfter");
        consumerType = prop.getProperty("consumerType");
        consumerAmount = Integer.valueOf(prop.getProperty("consumerAmount"));
        info = prop.getProperty("info");

        // extra content
        serverIp4Address = prop.getProperty("address.ip4");
        serverMacAddress = prop.getProperty("address.mac");
        dataKeyPwd = prop.getProperty("data.key.pwd");
        dataKey = prop.getProperty("data.key");
        env = prop.getProperty("env");
    }
    private LicenseParam initLicenseParam(){
        Class<LicenseMake> clazz = LicenseMake.class;
        Preferences pre = Preferences.userNodeForPackage(clazz);
        //设置对证书内容加密的对称密码
        CipherParam cipherParam = new DefaultCipherParam(keyStorePwd);
        /**
         * clazz 从哪个类Class.getResource()获得密钥库
         * priPath 从哪个类Class.getResource()获得密钥库
         * priAlias 密钥库的别名
         * keystorePwd 密钥库存储密码
         * privateKeyPwd 密钥库密码
         */
        KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(
                clazz,priPath,priAlias,keyStorePwd,privateKeyPwd);
        //返回生成证书时需要的参数
        return new DefaultLicenseParam(
                subject,pre,privateStoreParam,cipherParam);
    }

    public LicenseContent buildLicenseContent() throws ParseException{
        LicenseContent content = new LicenseContent();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        content.setSubject(subject);
        content.setConsumerAmount(consumerAmount);
        content.setConsumerType(consumerType);
        content.setHolder(DEFAULTHOLDERANDISSUER);
        content.setIssuer(DEFAULTHOLDERANDISSUER);
        content.setIssued(formatter.parse(issued));
        content.setNotBefore(formatter.parse(notBefore));
        content.setNotAfter(formatter.parse(notAfter));
        content.setInfo(info);

        Map<String, Object> extraInfo = new HashMap<String, Object>();
        extraInfo.put("IP4_ADDRESS", serverIp4Address);
        extraInfo.put("MAC_ADDRESS", serverMacAddress);
        extraInfo.put("ENV", env); // 系统运行环境标志
        content.setExtra(extraInfo);
        return content;
    }

    public void create(){
        try {
            LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(initLicenseParam());
            LicenseContent content = this.buildLicenseContent();
            // 类根目录
            String projectDir = System.getProperty("user.dir");
            // 项目的license资源目录
            String asmsApiDir = projectDir + "/asm-core/src/main/resources/";
            // 创建证书
            licenseManager.store(content, new File(asmsApiDir + licName));
            System.out.println("证书发布成功");
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成证书
     */
    public static void main(String[] args) {
        new LicenseMake("generate/licenseMakeConf.properties").create();
    }
}
